using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace TPL.Xna.Common
{
    public enum RenderType
    {
        Line,
        Point,
    }

    public class ShapeSprite : Sprite, IEnumerable<Vector2>
    {
        #region Fields

        /// <summary>1x1 pixel that creates the shape.</summary>
        private readonly Texture2D _pixel;

        /// <summary>List of vectors.</summary>
        private readonly List<Vector2> _segments = new List<Vector2>();

        public Vector2 this[int index]
        {
            get { return Position + _segments[index]; }
        }


        public RenderType RenderType { get; set; }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public IEnumerator<Vector2> GetEnumerator()
        {
            return _segments.Select(s => Position + s).GetEnumerator();
        }

        #endregion // Fields

        #region Properties

        /// <summary>
        /// Get/Set the thickness of the shape's edge.
        /// </summary>
        public float Thickness { get; set; }

        /// <summary>
        /// Gets the number of vectors which make up the primitive object.
        /// </summary>
        public int SegmentsCount
        {
            get { return _segments.Count; }
        }

        ///// <summary>
        ///// Gets the vector position from the list.
        ///// </summary>
        ///// <param name="index">The index to get from.</param>
        //public Vector2 GetVector(int index)
        //{
        //    return _segments[index];
        //}

        #endregion // Properties

        #region Sprite

        private float _lastAngle;

        protected override void InternalUpdate(GameTime gameTime, Rectangle clientBounds)
        {
            // Update rotating information before drawing
            if (Angle != _lastAngle)
            {
                Rotate(Angle - _lastAngle);
                _lastAngle = Angle;
            }
            base.InternalUpdate(gameTime, clientBounds);
        }

        protected override void InternalDraw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            switch (RenderType)
            {
                case RenderType.Line:
                    RenderLinePrimitive(spriteBatch);
                    break;
                case RenderType.Point:
                    RenderPointPrimitive(spriteBatch);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            base.InternalDraw(gameTime, spriteBatch);
        }

        #endregion

        #region Initialization | Dispose

        /// <summary>
        /// Creates a new primitive object.
        /// </summary>
        /// <param name="graphicsDevice">The graphics device object to use.</param>
        public ShapeSprite(GraphicsDevice graphicsDevice)
        {
            Thickness = 1f;
            Position = Vector2.Zero;

            // Create the pixel texture.
            _pixel = new Texture2D(graphicsDevice, 1, 1, false, SurfaceFormat.Color);
            _pixel.SetData(new[] { Color.White });
            //
        }

        /// <summary>
        /// Called when the primitive object is destroyed.
        /// </summary>
        ~ShapeSprite()
        {
            _pixel.Dispose();
            _segments.Clear();
        }

        #endregion // Initialization | Dispose

        #region List Manipulation Methods

        ///// <summary>
        ///// Adds a vector to the primitive object.
        ///// </summary>
        ///// <param name="position">The vector to add.</param>
        //public void AddVector(Vector2 position)
        //{
        //    _segments.Add(position);
        //}

        ///// <summary>
        ///// Inserts a vector into the primitive object.
        ///// </summary>
        ///// <param name="index">The index to insert it at.</param>
        ///// <param name="position">The vector to insert.</param>
        //public void InsertVector(int index, Vector2 position)
        //{
        //    _segments.Insert(index, position);
        //}

        ///// <summary>
        ///// Removes a vector from the primitive object.
        ///// </summary>
        ///// <param name="position">The vector to remove.</param>
        //public void RemoveVector(Vector2 position)
        //{
        //    _segments.Remove(position);
        //}

        ///// <summary>
        ///// Removes a vector from the primitive object.
        ///// </summary>
        ///// <param name="index">The index of the vector to remove.</param>
        //public void RemoveVector(int index)
        //{
        //    _segments.RemoveAt(index);
        //}

        ///// <summary>
        ///// Clears all vectors from the list.
        ///// </summary>
        //public void ClearVectors()
        //{
        //    _segments.Clear();
        //}

        #endregion // List Manipulation Methods

        #region Creation Methods

        ///// <summary> 
        ///// Create a line primitive.
        ///// </summary>
        ///// <param name="graphicsDevice">The graphics device object to use.</param>
        ///// <param name="start">Start of the line, in pixels.</param>
        ///// <param name="end">End of the line, in pixels.</param>
        //public static ShapeSprite CreateLine(GraphicsDevice graphicsDevice, Vector2 start, Vector2 end)
        //{
        //    ShapeSprite s = new ShapeSprite(graphicsDevice);
        //    s._segments.Clear();
        //    s._segments.Add(start);
        //    s._segments.Add(end);
        //    return s;
        //}

        ///// <summary>
        ///// Create a triangle primitive.
        ///// </summary>
        ///// <param name="graphicsDevice">The graphics device object to use.</param>
        ///// <param name="point1">Fist point, in pixels.</param>
        ///// <param name="point2">Second point, in pixels.</param>
        ///// <param name="point3">Third point, in pixels.</param>
        //public static ShapeSprite CreateTriangle(GraphicsDevice graphicsDevice, Vector2 point1, Vector2 point2, Vector2 point3)
        //{
        //    ShapeSprite s = new ShapeSprite(graphicsDevice);
        //    s._segments.Clear();
        //    s._segments.Add(point1);
        //    s._segments.Add(point2);
        //    s._segments.Add(point3);
        //    s._segments.Add(point1);
        //    return s;
        //}

        /// <summary>
        /// Create a mesh using given points.
        /// </summary>
        /// <param name="points"></param>
        /// <returns></returns>
        public ShapeSprite CreateMesh(params Vector2[] points)
        {
            _segments.Clear();
            _segments.AddRange(points);
            return this;
        }

        /// <summary>
        /// Create a square primitive.
        /// </summary>
        /// <param name="topLeft">Top left hand corner of the square.</param>
        /// <param name="bottomRight">Bottom right hand corner of the square.</param>
        public ShapeSprite CreateSquare(Vector2 topLeft, Vector2 bottomRight)
        {
            _segments.Clear();
            _segments.Add(topLeft);
            _segments.Add(new Vector2(topLeft.X, bottomRight.Y));
            _segments.Add(bottomRight);
            _segments.Add(new Vector2(bottomRight.X, topLeft.Y));
            _segments.Add(topLeft);
            return this;
        }


        ///// <summary>
        ///// Creates a circle starting from (0, 0).
        ///// </summary>
        ///// <param name="fRadius">The radius (half the width) of the circle.</param>
        ///// <param name="nSides">The number of sides on the circle. (64 is average).</param>
        //public void CreateCircle(float fRadius, int nSides)
        //{
        //    _segments.Clear();


        //    // Local variables.
        //    float fMax = MathHelper.TwoPi;
        //    float fStep = fMax/nSides;
        //    //


        //    // Create the full circle.
        //    for (float fTheta = fMax; fTheta >= -1; fTheta -= fStep)
        //    {
        //        _segments.Add(new Vector2(fRadius*(float) Math.Cos(fTheta),
        //                                  fRadius*(float) Math.Sin(fTheta)));
        //    }
        //    //
        //}


        ///// <summary>
        ///// Creates an ellipse starting from (0, 0) with the given width and height.
        ///// Vectors are generated using the parametric equation of an ellipse.
        ///// </summary>
        ///// <param name="semiMajorAxis">The width of the ellipse at its center.</param>
        ///// <param name="semiMinorAxis">The height of the ellipse at its center.</param>
        ///// <param name="sides">The number of sides on the ellipse. (64 is average).</param>
        //public void CreateEllipse(float semiMajorAxis, float semiMinorAxis, int sides)
        //{
        //    _segments.Clear();


        //    // Local variables.
        //    const float fMax = MathHelper.TwoPi;
        //    float fStep = fMax/sides;
        //    //
        //    // Create full ellipse.
        //    for (float fTheta = fMax; fTheta >= -1; fTheta -= fStep)
        //    {
        //        _segments.Add(new Vector2((float) (semiMajorAxis*Math.Cos(fTheta)),
        //                                  (float) (semiMinorAxis*Math.Sin(fTheta))));
        //    }
        //    //
        //}

        #endregion // Creation Methods

        #region Render Methods

        /// <summary>
        /// Render points of the primitive.
        /// </summary>
        /// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        public void RenderPointPrimitive(SpriteBatch spriteBatch)
        {
            // Validate.
            if (_segments.Count <= 0)
                return;
            //


            // Local variables.
            Vector2 vPosition1, vPosition2;
            float fAngle;

            // Run through the list of vectors.
            for (int i = _segments.Count - 1; i >= 1; --i)
            {
                // Store positions.
                vPosition1 = _segments[i - 1];
                vPosition2 = _segments[i];

                // Calculate the angle between the two vectors.
                fAngle = (float)Math.Atan2((vPosition2.Y - vPosition1.Y),
                                            (vPosition2.X - vPosition1.X));

                // Stretch the pixel between the two vectors.
                spriteBatch.Draw(_pixel,
                                 Position + _segments[i],
                                 null,
                                 Color,
                                 fAngle,
                                 new Vector2(0.5f, 0.5f),
                                 Thickness,
                                 SpriteEffects.None,
                                 ZIndex);
            }
            //
        }


        ///// <summary>
        ///// Render points of the primitive.
        ///// </summary>
        ///// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        ///// <param name="angle">The counterclockwise rotation in radians. (0.0f is default).</param>
        ///// <param name="pivot">Position in which to rotate around.</param>
        //public void RenderPointPrimitive(SpriteBatch spriteBatch, float angle, Vector2 pivot)
        //{
        //    // Validate.
        //    if (_segments.Count <= 0)
        //        return;

        //    // Rotate object based on pivot.
        //    Rotate(angle, pivot);

        //    // Local variables.
        //    Vector2 vPosition1, vPosition2;
        //    float fAngle;

        //    // Run through the list of vectors.
        //    for (int i = _segments.Count - 1; i >= 1; --i)
        //    {
        //        // Store positions.
        //        vPosition1 = _segments[i - 1];
        //        vPosition2 = _segments[i];

        //        // Calculate the angle between the two vectors.
        //        fAngle = (float) Math.Atan2((vPosition2.Y - vPosition1.Y),
        //                                    (vPosition2.X - vPosition1.X));

        //        // Stretch the pixel between the two vectors.
        //        spriteBatch.Draw(_pixel,
        //                         Position + _segments[i],
        //                         null,
        //                         Colour,
        //                         fAngle,
        //                         new Vector2(0.5f, 0.5f),
        //                         Thickness,
        //                         SpriteEffects.None,
        //                         ZIndex);
        //    }
        //}


        /// <summary>
        /// Render the lines of the primitive.
        /// </summary>
        /// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        private void RenderLinePrimitive(SpriteBatch spriteBatch)
        {
            // Validate.
            if (_segments.Count < 2)
                return;

            // Local variables.
            Vector2 vPosition1, vPosition2;
            float fDistance, fAngle;

            // Run through the list of vectors.
            for (int i = _segments.Count - 1; i >= 1; --i)
            {
                // Store positions.
                vPosition1 = _segments[i - 1];
                vPosition2 = _segments[i];

                // Calculate the distance between the two vectors.
                fDistance = Vector2.Distance(vPosition1, vPosition2);

                // Calculate the angle between the two vectors.
                fAngle = (float)Math.Atan2((vPosition2.Y - vPosition1.Y),
                                            (vPosition2.X - vPosition1.X));

                // Stretch the pixel between the two vectors.
                spriteBatch.Draw(_pixel,
                                 Position + vPosition1,
                                 null,
                                 Color,
                                 fAngle,
                                 new Vector2(0, 0.5f),
                                 new Vector2(fDistance, Thickness),
                                 SpriteEffects.None,
                                 ZIndex);
            }
            // Stretch the pixel between the two vectors.
            spriteBatch.Draw(_pixel,
                             Position + Origin,
                             null,
                             Color.Red,
                             Angle,
                             new Vector2(0, 0.5f),
                             new Vector2(1, Thickness),
                             SpriteEffects.None,
                             ZIndex);
        }


        ///// <summary>
        ///// Render the lines of the primitive.
        ///// </summary>
        ///// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        ///// <param name="angle">The counterclockwise rotation in radians. (0.0f is default).</param>
        ///// <param name="pivot">Position in which to rotate around.</param>
        //public void RenderLinePrimitive(SpriteBatch spriteBatch, float angle, Vector2 pivot)
        //{
        //    // Validate.
        //    if (_segments.Count < 2)
        //        return;

        //    // Rotate object based on pivot.
        //    Rotate(angle, pivot);

        //    // Local variables.
        //    Vector2 vPosition1, vPosition2;
        //    float fDistance, fAngle;

        //    // Run through the list of vectors.
        //    for (int i = _segments.Count - 1; i >= 1; --i)
        //    {
        //        // Store positions.
        //        vPosition1 = _segments[i - 1];
        //        vPosition2 = _segments[i];

        //        // Calculate the distance between the two vectors.
        //        fDistance = Vector2.Distance(vPosition1, vPosition2);

        //        // Calculate the angle between the two vectors.
        //        fAngle = (float) Math.Atan2((vPosition2.Y - vPosition1.Y),
        //                                    (vPosition2.X - vPosition1.X));

        //        // Stretch the pixel between the two vectors.
        //        spriteBatch.Draw(_pixel,
        //                         Position + vPosition1,
        //                         null,
        //                         Colour,
        //                         fAngle,
        //                         new Vector2(0, 0.5f),
        //                         new Vector2(fDistance, Thickness),
        //                         SpriteEffects.None,
        //                         ZIndex);
        //    }
        //}


        ///// <summary>
        ///// Render primitive by using a square algorithm.
        ///// </summary>
        ///// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        //public void RenderSquarePrimitive(SpriteBatch spriteBatch)
        //{
        //    // Validate.
        //    if (_segments.Count < 2)
        //        return;

        //    // Local variables.
        //    Vector2 vPosition1, vPosition2, vLength;
        //    float fDistance, fAngle = 0f;
        //    int nCount;

        //    // Run through the list of vectors.
        //    for (int i = _segments.Count - 1; i >= 1; --i)
        //    {
        //        // Store positions.
        //        vPosition1 = _segments[i - 1];
        //        vPosition2 = _segments[i];

        //        // Calculate the distance between the two vectors.
        //        fDistance = Vector2.Distance(vPosition1, vPosition2);

        //        // Calculate the angle between the two vectors.
        //        fAngle = (float) Math.Atan2((vPosition2.Y - vPosition1.Y),
        //                                    (vPosition2.X - vPosition1.X));

        //        // Calculate length.
        //        vLength = vPosition2 - vPosition1;
        //        vLength.Normalize();

        //        // Calculate count for roundness.
        //        nCount = (int) Math.Round(fDistance);

        //        // Run through and render the primitive.
        //        while (nCount-- > 0)
        //        {
        //            // Increment position.
        //            vPosition1 += vLength;

        //            // Stretch the pixel between the two vectors.
        //            spriteBatch.Draw(_pixel,
        //                             Position + vPosition1,
        //                             null,
        //                             Colour,
        //                             0,
        //                             Vector2.Zero,
        //                             Thickness,
        //                             SpriteEffects.None,
        //                             ZIndex);
        //        }
        //    }
        //}


        ///// <summary>
        ///// Render primitive by using a square algorithm.
        ///// </summary>
        ///// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        ///// <param name="angle">The counterclockwise rotation in radians. (0.0f is default).</param>
        ///// <param name="pivot">Position in which to rotate around.</param>
        //public void RenderSquarePrimitive(SpriteBatch spriteBatch, float angle, Vector2 pivot)
        //{
        //    // Validate.
        //    if (_segments.Count < 2)
        //        return;

        //    // Rotate object based on pivot.
        //    Rotate(angle, pivot);

        //    // Local variables.
        //    Vector2 vPosition1, vPosition2, vLength;
        //    float fDistance, fAngle = 0f;
        //    int nCount;

        //    // Run through the list of vectors.
        //    for (int i = _segments.Count - 1; i >= 1; --i)
        //    {
        //        // Store positions.
        //        vPosition1 = _segments[i - 1];
        //        vPosition2 = _segments[i];

        //        // Calculate the distance between the two vectors.
        //        fDistance = Vector2.Distance(vPosition1, vPosition2);

        //        // Calculate the angle between the two vectors.
        //        fAngle = (float) Math.Atan2((vPosition2.Y - vPosition1.Y),
        //                                    (vPosition2.X - vPosition1.X));

        //        // Calculate length.
        //        vLength = vPosition2 - vPosition1;
        //        vLength.Normalize();

        //        // Calculate count for roundness.
        //        nCount = (int) Math.Round(fDistance);

        //        // Run through and render the primitive.
        //        while (nCount-- > 0)
        //        {
        //            // Increment position.
        //            vPosition1 += vLength;

        //            // Stretch the pixel between the two vectors.
        //            spriteBatch.Draw(_pixel,
        //                             Position + vPosition1,
        //                             null,
        //                             Colour,
        //                             0,
        //                             Vector2.Zero,
        //                             Thickness,
        //                             SpriteEffects.None,
        //                             ZIndex);
        //        }
        //    }
        //}


        ///// <summary>
        ///// Render primitive by using a round algorithm.
        ///// </summary>
        ///// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        //public void RenderRoundPrimitive(SpriteBatch spriteBatch)
        //{
        //    // Validate.
        //    if (_segments.Count < 2)
        //        return;
        //    //


        //    // Local variables.
        //    Vector2 vPosition1, vPosition2, vLength;
        //    float fDistance, fAngle;
        //    int nCount;
        //    //


        //    // Run through the list of vectors.
        //    for (int i = _segments.Count - 1; i >= 1; --i)
        //    {
        //        // Store positions.
        //        vPosition1 = _segments[i - 1];
        //        vPosition2 = _segments[i];
        //        //


        //        // Calculate the distance between the two vectors.
        //        fDistance = Vector2.Distance(vPosition1, vPosition2);

        //        // Calculate the angle between the two vectors.
        //        fAngle = (float) Math.Atan2((vPosition2.Y - vPosition1.Y),
        //                                    (vPosition2.X - vPosition1.X));

        //        // Calculate length.
        //        vLength = vPosition2 - vPosition1;
        //        vLength.Normalize();

        //        // Calculate count for roundness.
        //        nCount = (int) Math.Round(fDistance);
        //        //


        //        // Run through and render the primitive.
        //        while (nCount-- > 0)
        //        {
        //            // Increment position.
        //            vPosition1 += vLength;

        //            // Stretch the pixel between the two vectors.
        //            spriteBatch.Draw(_pixel,
        //                             Position + vPosition1 + 0.5f*(vPosition2 - vPosition1),
        //                             null,
        //                             Colour,
        //                             fAngle,
        //                             new Vector2(0.5f, 0.5f),
        //                             new Vector2(fDistance, Thickness),
        //                             SpriteEffects.None,
        //                             ZIndex);
        //        }
        //        //
        //    }
        //    //
        //}


        ///// <summary>
        ///// Render primitive by using a round algorithm.
        ///// </summary>
        ///// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        ///// <param name="angle">The counterclockwise rotation in radians. (0.0f is default).</param>
        ///// <param name="pivot">Position in which to rotate around.</param>
        //public void RenderRoundPrimitive(SpriteBatch spriteBatch, float angle, Vector2 pivot)
        //{
        //    // Validate.
        //    if (_segments.Count < 2)
        //        return;

        //    // Rotate object based on pivot.
        //    Rotate(angle, pivot);

        //    // Local variables.
        //    Vector2 vPosition1, vPosition2, vLength;
        //    float fDistance, fAngle;
        //    int nCount;

        //    // Run through the list of vectors.
        //    for (int i = _segments.Count - 1; i >= 1; --i)
        //    {
        //        // Store positions.
        //        vPosition1 = _segments[i - 1];
        //        vPosition2 = _segments[i];

        //        // Calculate the distance between the two vectors.
        //        fDistance = Vector2.Distance(vPosition1, vPosition2);

        //        // Calculate the angle between the two vectors.
        //        fAngle = (float) Math.Atan2((vPosition2.Y - vPosition1.Y),
        //                                    (vPosition2.X - vPosition1.X));

        //        // Calculate length.
        //        vLength = vPosition2 - vPosition1;
        //        vLength.Normalize();

        //        // Calculate count for roundness.
        //        nCount = (int) Math.Round(fDistance);

        //        // Run through and render the primitive.
        //        while (nCount-- > 0)
        //        {
        //            // Increment position.
        //            vPosition1 += vLength;

        //            // Stretch the pixel between the two vectors.
        //            spriteBatch.Draw(_pixel,
        //                             Position + vPosition1 + 0.5f*(vPosition2 - vPosition1),
        //                             null,
        //                             Colour,
        //                             fAngle,
        //                             new Vector2(0.5f, 0.5f),
        //                             new Vector2(fDistance, Thickness),
        //                             SpriteEffects.None,
        //                             ZIndex);
        //        }
        //    }
        //}


        ///// <summary>
        ///// Render primitive by using a point and line algorithm.
        ///// </summary>
        ///// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        //public void RenderPolygonPrimitive(SpriteBatch spriteBatch)
        //{
        //    // Validate.
        //    if (_segments.Count < 2)
        //        return;

        //    // Local variables.
        //    Vector2 vPosition1, vPosition2;
        //    float fDistance, fAngle;

        //    // Run through the list of vectors.
        //    for (int i = _segments.Count - 1; i >= 1; --i)
        //    {
        //        // Store positions.
        //        vPosition1 = _segments[i - 1];
        //        vPosition2 = _segments[i];

        //        // Calculate the distance between the two vectors.
        //        fDistance = Vector2.Distance(vPosition1, vPosition2);

        //        // Calculate the angle between the two vectors.
        //        fAngle = (float) Math.Atan2((vPosition2.Y - vPosition1.Y),
        //                                    (vPosition2.X - vPosition1.X));

        //        // Stretch the pixel between the two vectors.
        //        spriteBatch.Draw(_pixel,
        //                         Position + vPosition1 + 0.5f*(vPosition2 - vPosition1),
        //                         null,
        //                         Colour,
        //                         fAngle,
        //                         new Vector2(0.5f, 0.5f),
        //                         new Vector2(fDistance, Thickness),
        //                         SpriteEffects.None,
        //                         ZIndex);

        //        // Render the points of the polygon.
        //        spriteBatch.Draw(_pixel,
        //                         Position + vPosition1,
        //                         null,
        //                         Colour,
        //                         fAngle,
        //                         new Vector2(0.5f, 0.5f),
        //                         Thickness,
        //                         SpriteEffects.None,
        //                         ZIndex);
        //    }
        //}


        ///// <summary>
        ///// Render primitive by using a point and line algorithm.
        ///// </summary>
        ///// <param name="spriteBatch">The sprite batch to use to render the primitive object.</param>
        ///// <param name="angle">The counterclockwise rotation in radians. (0.0f is default).</param>
        ///// <param name="pivot">Position in which to rotate around.</param>
        //public void RenderPolygonPrimitive(SpriteBatch spriteBatch, float angle, Vector2 pivot)
        //{
        //    // Validate.
        //    if (_segments.Count < 2)
        //        return;

        //    // Rotate object based on pivot.
        //    Rotate(angle, pivot);

        //    // Local variables.
        //    Vector2 vPosition1, vPosition2;
        //    float fDistance, fAngle;

        //    // Run through the list of vectors.
        //    for (int i = _segments.Count - 1; i >= 1; --i)
        //    {
        //        // Store positions.
        //        vPosition1 = _segments[i - 1];
        //        vPosition2 = _segments[i];

        //        // Calculate the distance between the two vectors.
        //        fDistance = Vector2.Distance(vPosition1, vPosition2);

        //        // Calculate the angle between the two vectors.
        //        fAngle = (float) Math.Atan2((vPosition2.Y - vPosition1.Y),
        //                                    (vPosition2.X - vPosition1.X));

        //        // Stretch the pixel between the two vectors.
        //        spriteBatch.Draw(_pixel,
        //                         Position + vPosition1 + 0.5f*(vPosition2 - vPosition1),
        //                         null,
        //                         Colour,
        //                         fAngle,
        //                         new Vector2(0.5f, 0.5f),
        //                         new Vector2(fDistance, Thickness),
        //                         SpriteEffects.None,
        //                         ZIndex);

        //        // Render the points of the polygon.
        //        spriteBatch.Draw(_pixel,
        //                         Position + vPosition1,
        //                         null,
        //                         Colour,
        //                         fAngle,
        //                         new Vector2(0.5f, 0.5f),
        //                         Thickness,
        //                         SpriteEffects.None,
        //                         ZIndex);
        //    }
        //}

        #endregion // Render Methods

        #region Public Methods

        /// <summary>
        /// Rotate primitive object based on pivot.
        /// </summary>
        private void Rotate(float angle)
        {
            // Subtract pivot from all points.
            for (int i = _segments.Count - 1; i >= 0; --i)
                _segments[i] -= Origin;

            // Rotate about the origin.
            Matrix mat = Matrix.CreateRotationZ(angle);
            for (int i = _segments.Count - 1; i >= 0; --i)
                _segments[i] = Vector2.Transform(_segments[i], mat);

            // Add pivot to all points.
            for (int i = _segments.Count - 1; i >= 0; --i)
                _segments[i] += Origin;
            //
        }

        #endregion // Public Methods
    }
}